package com.kangjia.general.controller;

import java.io.Serializable;
import java.util.List;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.kangjia.general.controller.call.Call;
import com.kangjia.general.dao.query.OperType;
import com.kangjia.general.dao.query.Param;
import com.kangjia.general.dao.query.QueryParam;
import com.kangjia.general.service.GeneralAnnotationService;
import com.kangjia.holder.VariableThreadLocal;
import com.kangjia.model.m1.entity.Employee;
import com.kangjia.response.AbstractResponse;
import com.kangjia.response.ErrorResponse;
import com.kangjia.response.ObjectResponse;
import com.kangjia.response.PageResponse;
import com.kangjia.response.SuccessResponse;

import lombok.extern.slf4j.Slf4j;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

/**
 * 基础
 * 
 * @author sunshulin
 *
 */
@Slf4j
public abstract class AbstractController<T> {
	
	protected static final String HW_INC_KEY = "hwinc";

	@Autowired
	private GeneralAnnotationService<T> generalAnnotationService;
	@Autowired
	protected JedisPool jedisPool;

	protected ObjectResponse<T> editorx(T entity) {
		log.debug("editor 实体对象数据={}", entity);
		Serializable id = getPrimary(entity);
		T old = entity;
		if (id != null) {
			old = generalAnnotationService.get(getClazz(), id);
		}
		if (old != null) {
			BeanUtils.copyProperties(entity, old, ignores());
		}
		generalAnnotationService.saveOrUpdate(old);
		return new ObjectResponse<>(old);
	}

	protected AbstractResponse find(Serializable id, Call<T> call) {
		T entity = findById(id, call);
		if (entity == null) {
			return new ErrorResponse("没有发现记录");
		}
		return new ObjectResponse<>(entity);
	}

	protected T findById(Serializable id, Call<T> call) {
		T entity = generalAnnotationService.get(getClazz(), id);
		if (entity == null) {
			return null;
		}
		if (call != null) {
			call.call(entity);
		}
		return entity;
	}

	protected AbstractResponse update(Serializable id, Call<T> call) {
		if (call != null) {
			T entity = findById(id, call);
			if (entity != null) {
				call.call(entity);
				generalAnnotationService.saveOrUpdate(entity);
				return new SuccessResponse("操作成功");
			} else {
				return new ErrorResponse("没有发现记录");
			}
		} else {
			return new ErrorResponse("call is null");
		}
	}
	
	protected AbstractResponse deleteById(Serializable id, Call<T> call) {
		T entity = findById(id, null);
		if (entity != null) {
			generalAnnotationService.delete(getClazz(), id);
		}
		if (call != null) {
			call.call(entity);
		}
		return new SuccessResponse("操作成功");
	}

	protected AbstractResponse delete(Serializable id, Call<T> call) {
		T entity = findById(id, null);
		if (entity != null) {
			status(entity);
			generalAnnotationService.saveOrUpdate(entity);
		}
		if (call != null) {
			call.call(entity);
		}
		return new SuccessResponse("操作成功");
	}

	protected PageResponse<T> query() {
		return query(null, null);
	}

	protected PageResponse<T> query(Call<T> call) {
		return query(null, call);
	}

	protected PageResponse<T> query(QueryParam queryParam) {
		return query(queryParam, null);
	}

	protected PageResponse<T> query(QueryParam queryParam, Call<T> call) {
		List<T> list = generalAnnotationService.pager(getClazz(), queryParam);
		for (T entity : list) {
			if (call != null) {
				call.call(entity);
			}
		}
		return new PageResponse<>(queryParam != null ? queryParam.getTotal() : null, list);
	}

	public abstract Serializable getPrimary(T entity);

	public abstract Class<T> getClazz();

	public String[] ignores() {
		return new String[] {};
	}

	public abstract void status(T entity);

	public Employee getEmployee() {
		Employee employee = VariableThreadLocal.get("login");
		if (employee == null) {
			throw new RuntimeException("本地变量中获取不到员工信息.需从新登陆.");
		}
		return employee;
	}

	public void settingOrg(QueryParam param) {
		Employee employee = getEmployee();
		param.addParam(new Param<String>("code", OperType.like, employee.getOrgCode()));
	}

	protected void hset(String key, String field, String value) {
		Jedis jedis = jedisPool.getResource();
		try {
			jedis.hset(key, field, value);
		} finally {
			jedis.close();
		}
	}

	protected String hget(String key, String field) {
		Jedis jedis = jedisPool.getResource();
		try {
			return jedis.hget(key, field);
		} finally {
			jedis.close();
		}
	}

	protected void hdel(String key, String field) {
		Jedis jedis = jedisPool.getResource();
		try {
			jedis.hdel(key, field);
		} finally {
			jedis.close();
		}
	}

	protected Long hinc(String key, String field) {
		Jedis jedis = jedisPool.getResource();
		try {
			return jedis.hincrBy(key, field, 1L);
		} finally {
			jedis.close();
		}
	}
}
